package Model.Protocole;

import Share.Constante.ConstanteIdException;
import Share.Protocole.Exception.AddToMessageProtocoleException;
import Share.Protocole.Exception.GetMessageProtocoleException;
import Share.Protocole.Exception.OpenStreamProtocoleException;
import Share.Protocole.Exception.ProtocoleException;
import Share.Protocole.Exception.ReceiveMessageProtocoleException;
import Share.Protocole.Exception.SendMessageProtocoleException;
import Share.Protocole.InterfaceProtocole;
import Share.Transport.Exception.OpenStreamTransportException;
import Share.Transport.Exception.TransportException;
import Share.Transport.InterfaceTransport;
import message.Exception.AddToMessageMessageException;
import message.Exception.GetMessageMessageException;
import message.Message;

/**
 *
 * @author Alex
 */
public class ProtocoleClient implements InterfaceProtocole{
    
    private InterfaceTransport transport;
    private Message messageSentByClient;
    private Message messageSentByServer;

    /**
     * constructeur de la couche protocole
     * @param trans 
     */
    public ProtocoleClient(InterfaceTransport trans) {
        transport = trans;
        messageSentByClient = null;
        messageSentByServer = null;
    }
    
    /**
     * Méthode pour ouvrir les flux
     * @throws OpenStreamProtocoleException 
     */
    private void openStream() throws OpenStreamProtocoleException{
        try{
            transport.connectToServer();
            transport.openInputStream();
            transport.openOutputStream();
        } catch(TransportException e){
            throw new OpenStreamProtocoleException(ConstanteIdException.OPEN_STREAM_PROTOCOLE_EXCEPTION);
        }
    }

    /**
     * Reception du message envoyé par le client
     * @throws ReceiveMessageProtocoleException 
     */
    @Override
    public void receive() throws ReceiveMessageProtocoleException {
        try {
            messageSentByClient = (Message) transport.receive();
            transport.closeStream();
          } catch (TransportException e) {
            throw new ReceiveMessageProtocoleException(e.getId());
        }
    }

    /**
     * envoie du message au client
     * @throws SendMessageProtocoleException 
     */
    @Override
    public void send() throws SendMessageProtocoleException {
        try {
            openStream();
            transport.send(messageSentByServer);
        } catch (TransportException cstex) {
            throw new SendMessageProtocoleException(cstex.getId());
        } catch(ProtocoleException e){
            throw new SendMessageProtocoleException(e.getId());
        }
    }

    /**
     * Recuperation d'un parametre du Message envoyé par le Client
     * @param choixMessage
     * @return
     * @throws GetMessageProtocoleException 
     */
    @Override
    public Object getMessage(Integer choixMessage) throws GetMessageProtocoleException {
        try {
            if (choixMessage == null) {
                throw new GetMessageProtocoleException(ConstanteIdException.GET_MESSAGE_PROTOCOLE_EXCEPTION);
            }
            return messageSentByClient.getMessage(choixMessage);
        } catch (GetMessageMessageException e) {
            throw new GetMessageProtocoleException(e.getId());
        }
    }

    /**
     * Ajoute un parametre au message a envoye au Client
     * @param choixMessage
     * @param param 
     */
    @Override
    public void addToMessage(Integer choixMessage, Object param) throws AddToMessageProtocoleException {
        try {
            messageSentByServer.addMessage(choixMessage, param);
        } catch (AddToMessageMessageException e) {
            throw new AddToMessageProtocoleException(e.getId());
        }
    }

    /**
     * Méthode pour instancier un nouveau Message à envoyé
     */
    @Override
    public void newMessage() {
        messageSentByServer = new Message();
    }
}
